Helper.using('py.Figures', function (ns) {

    ns.Line = function (params) {
        ns.LinearObject.call(this, params);
        this.setType('Line');

        this.visual(new Kinetic.Line({
            points: [-1,-1,-1,-1],
            stroke:"black",
            strokeWidth:2,
            lineCap:"round",
            lineJoin:"round"
        }));

        this.update = function (viewPort) {
            if(!this.formed()) return;
            var bound = viewPort.getBound(),
                x1 = bound[0].x, x2 = bound[1].x,
                y1 = bound[1].y, y2 = bound[0].y;
            var equation = this.getEquation();

            var p = equation.inbound(x1, x2, y1, y2);
            p = [viewPort.getPixelPoint(p[0]), viewPort.getPixelPoint(p[1])];
            this.visual().setPoints([p[0].x, p[0].y, p[1].x, p[1].y]);
        };

        this.drawFunc = function (viewPort) {
            this.update(viewPort);
            this.layer().draw();
        };

        this.getMagnitude = function () {
            return this.getDirectionVector().getLength();
        };

    };

    ns.Line2Point = function (params) {
        params = Helper.extend( {
            points : []
        }, params);

        ns.Line.call(this, params);
        this.setType('Line2Point');


        this.formed = function () {
            var flag =  params && params.points && params.points.length && params.points.length == 2;
            return flag && this.getDirectionVector().getLength();
        };


        this.getAnchor = function () {
            return  params.points[0];
        };

        this.getDirectionVector = function () {
            return new ns.Vector2Point({head:params.points[0], tail:params.points[1]});
        };

        this.setPoints = function(points) {
            params.points = points;

        };

        this.setPoint = function (index, point) {
            params.points[index] = point;
        }
    };

    ns.ParallelLine = function (params) {
        ns.Line.call(this, params);
        this.setType('ParallelLine');

        params = Helper.extend({
            anchor:null,
            linear:null
        }, params);

        this.formed = function () {
            return params.anchor && params.linear;
        };

        this.getAnchor = function () {
            return params.anchor;
        };

        this.getDirectionVector = function () {
            return params.linear.getDirectionVector();
        };

        this.setAnchor = function (anchor) {
            params.anchor = anchor;
        };

        this.setLinear = function (linear) {
            params.linear = linear;
        }

    };

    ns.PerpendicularLine = function(params){
        ns.Line.call(this, params);
        this.setType('PerpendicularLine');

        params = Helper.extend({
            anchor:null,
            linear:null
        }, params);

        var anchor, linearObject, vector, _vector;

        var initialize = function(){
            anchor = params.anchor;
            linearObject = params.linear;
            _vector = linearObject.getDirectionVector();
            // debug
            //_vector = linearObject.vector;
            vector = new ns.Vector2Point({head:_vector.getHead(), tail:_vetor.getTail()});
        };

        initialize();


        this.getAnchor = function () {
            return anchor;
        };

        this.getDirectionVector = function () {
            return vector.getPerpendicularVector();
        };

        this.setAnchor = function(anchor){
            params.anchor = anchor;
            initialize();
        };

        this.setLinear = function(linear){
            params.linear = linear;
            initialize();
        };
    };

    ns.PerpendicularBisector = function(params){
        ns.Line.call(this, params);
        this.setType('PerpendicularBisector');

        params = Helper.extend({
            points:null
        }, params);

        var anchor, vector, pointA, pointB;

        var initialize = function(){
            pointA = params.points[0];
            pointB = params.points[1];
            anchor = new ns.MidPoint({ends:[pointA, pointB]});
            vector = new ns.Vector2Point({head:pointA, tail:pointB});
        };

        initialize();


        this.getAnchor = function () {
            return anchor;
        };

        this.getDirectionVector = function () {
            return vector.getPerpendicularVector();
        };

        this.setPoints = function(points){
            params.points = points;
            initialize();
        }


    };

});